package DataBaseManager;

import java.io.Serializable;
import java.util.ArrayList;
import DataType.MyDataType;
import DataType.MyDataType.MY_TYPE;

public class Table implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	ArrayList<Field> fields;
	private String name;
	//ArrayList<Field> pK;
	ArrayList<Readable> references;
	private Data data;
	

	
	public Table(String tbname){
		this.name = tbname;
		fields = new ArrayList<Field>();
		data = new Data();
	}
	
	public boolean setPrivateKey(int fieldIndex)
	{
		for (int i=0;i<getNumberOfRow();i++) {	
			if(getValue(fieldIndex, i).getType() == MY_TYPE.MY_NULL)
				return false;
			for(int j=0;i<i;j++)
			{
				if(getValue(fieldIndex, i).isEqual(getValue(fieldIndex, j)))
					return false;
			}
		}
		for(int i=0;i<fields.size();i++)
		{
			if(fields.get(i).PrivateKey())
				fields.get(i).setPrivateKey(false );
		}
		fields.get(fieldIndex).setPrivateKey(true);
		return true;
	}
	public boolean setAlowNull(int fieldIndex,boolean isAlow)
	{
		if(isAlow)
		{
			fields.get(fieldIndex).setAllowNull(true);
			return true;
		}	
		for (int i=0;i<getNumberOfRow();i++) {	
			if(getValue(fieldIndex, i).getType() == MY_TYPE.MY_NULL)
				return false;
		}
		fields.get(fieldIndex).setAllowNull(false);
		return true;
	}
	
	
	/*public ArrayList<Field> getPK(){
		return pK;
	}*/
	public int getNumberOfRow()
	{
		return data.rows.size();
	}
	public Row createNewDataRow()
	{
		return new Row(fields.size());
	}

	public Row getDataRow(int rowIndex)
	{
		if(rowIndex >=0 && rowIndex < data.rows.size())
			return data.rows.get(rowIndex);
		return null;
	}
	public MyDataType getValue(int colIndex,int rowIndex)
	{
		return data.rows.get(rowIndex).getValue(colIndex);
	}
	public int fieldIndex(String colName)
	{
		for (int i = 0;i<fields.size() ; i++) {		
			if(colName.equals(fields.get(i).getName()))
			{
				return i;
			}
		}
		return -1;
	}
	public String getFieldName(int colIndex)
	{
		return fields.get(colIndex).getName();
	}
	public ArrayList<Field> getFields(){
		return fields;
	}
	public void setFields(ArrayList<Field> input){
		this.fields = input;
	}
	public void deleteDataRow(int rowIndex)
	{
		data.delete(rowIndex);
	}
	public void clearData()
	{
		data.rows.clear();
	}
	public String getName(){
		return name.toLowerCase();
	}
	public void setName(String _name){
		name = _name;
	}
	public Data getData(){
		return this.data;
	}
	
	private boolean isValid(int colIndex,MyDataType value)
	{
		if(colIndex<0 || colIndex >= fields.size())
			return false;
		Field field = fields.get(colIndex);
		if(value.getType() == MY_TYPE.MY_NULL)
			return field.AllowNull();
		if(field.Unique())
		{
			for (Row row : data.rows) {
				if(row.getValue(colIndex) != null && row.getValue(colIndex).isEqual(value))
					return false;
			}
		}
				
		return (field.getType() == MY_TYPE.MY_NULL)||(field.getType() == value.getType());
	}
	
	public boolean setData(String fieldName,int rowIndex ,MyDataType value)
	{

		int index = fieldIndex(fieldName);
		if(index == -1)
			return false;
		return setData(rowIndex, index, value);
	}

	public boolean setData(int rowIndex, int col, MyDataType value) {
		if(getValue(col, rowIndex).isEqual(value))
			return true;
		if(isValid( col, value))
		{
			data.rows.get(rowIndex).setValue(col, value);
			return true;
		}
		
		return false;
	}
	public void addDataColumn()
	{
		for (Row row : data.rows) {
			row.add(MyDataType.getNull());
		}
	}
	public boolean checkConvertData(int col,MY_TYPE newType)
	{
		for (Row row : data.rows) {
			MyDataType value = row.getValue(col);
			if(value.getType() != MY_TYPE.MY_NULL)
			{
				if(value.setType(newType).getType() == MY_TYPE.MY_NULL)
				{
					return false;
				}
			}
		}
		return true;
	}
	public void setDataType(int col,MY_TYPE newType)
	{
		if(col<0 || col>= fields.size())
			return ;
		fields.get(col).setType(newType);
		int i=0;
		while(i<getNumberOfRow())
		{
			MyDataType value = getValue(col, i).setType(newType);
			if(isValid(col, value))
			{
				setData(i, col,value);
				i++;
			}
			else
			{
				deleteDataRow(i);
			}
		}
		
	}
	public int insertData(Row row)
	{
		Row newRow = new Row(); 
		for(int i=0;i<fields.size();i++)
		{
			if(i>=row.values.size())
			{
				newRow.values.add(null);
			}
			MyDataType value = row.getValue(i);
			if(isValid(i, value))
			{
				newRow.values.add(value);
			}
			else
			{
				return i;
			}
		}
		data.insert(newRow);
		return -1;
		
	}
	
	
	
	
}
